package generator.statistics;

import generator.driver.GeneratorStatistics;
import generator.filedeal.ReadFileDeal;
import generator.structure.Pair;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

public class SetCurrentDistributions {

	ReadFileDeal fileReader;
	double size = 0.02;
	
	public SetCurrentDistributions(ReadFileDeal fileReader, double size) {
		this.fileReader = fileReader;
		this.size = size;
	}

	public void setMutualDistributions() {
		
		Map<Pair<Integer, Integer>, ArrayList<Pair<Pair<String, String>, Integer>>> mutualInfoAccum = 
				new HashMap<Pair<Integer, Integer>, ArrayList<Pair<Pair<String, String>, Integer>>>();

		int size = GeneratorStatistics.mutual.getListLength();

		for (int i = 0; i < size; i++) {// for each pair

			ArrayList<Integer> mutual = GeneratorStatistics.mutual.get(i);

//			Pair<Integer, Integer> pair = new Pair<Integer, Integer>(
//					mutual.get(0), mutual.get(1));

			ArrayList<Map<String, Integer>> currentDistributionList = fileReader
					.readData(mutual);

			int fileNum = 0;
			ArrayList<Integer> rowsArray = new ArrayList<Integer>();

			if (i == 0) {
				fileNum = fileReader.getFileNum();
				rowsArray = fileReader.getRowsArray();
			}

			//System.out.println("fileDealer");
			//fileDealer(currentDistributionList, rowsArray);
			
			GeneratorStatistics.mutual.setDistributionRowArray(i,
					currentDistributionList, rowsArray);

		}

	}

	private void fileDealer(
			ArrayList<Map<String, Integer>> currentDistributionList, ArrayList<Integer> rowsArray) {

		ArrayList<Map<String, Integer>> newCurrentDistributionList = new ArrayList<Map<String, Integer>>();
		ArrayList<Integer> newRowsArray = new  ArrayList<Integer>();
		
		System.out.println(rowsArray.size() + " " + currentDistributionList.size());
		
		for(int i = 0; i < rowsArray.size(); i++) {
			
			Map<String, Integer> distribution = currentDistributionList.get(i);
			
			Map<String, Integer> newDistribution = new HashMap<String, Integer>();
			
			Set<String> keys = distribution.keySet();
			
			int row = 0;
			for(Iterator<String> ite = keys.iterator(); ite.hasNext();) {
				String oneKey = ite.next();
				int frequency = distribution.get(oneKey);
				frequency = (int)((double)frequency * 0.02);
				if(frequency < 1) frequency = 1;
				newDistribution.put(oneKey, frequency);
				row += frequency;
			}
			newRowsArray.add(row);
			newCurrentDistributionList.add(newDistribution);
			
		}
		
		currentDistributionList = newCurrentDistributionList;
		rowsArray = newRowsArray;
		
		//System.out.println("which has been changed" + rowsArray);
		//System.out.println(currentDistributionList);
	}

	public void setCircleDistributions() {
		Map<ArrayList<Integer>, ArrayList<Pair<ArrayList<String>, Integer>>> CircleInfoAccum = 
				new HashMap<ArrayList<Integer>, ArrayList<Pair<ArrayList<String>, Integer>>>();

		int fileNum = 0;
		ArrayList<Integer> rowsArray = new ArrayList<Integer>();

		int size = GeneratorStatistics.circle.getListLength();
		
		for (int i = 0; i < size; i++) {

			ArrayList<Integer> circlein = GeneratorStatistics.circle.get(i);

			ArrayList<Map<String, Integer>> currentDistributionList = fileReader
					.readData(circlein);

			if (i == 0) {
				fileNum = fileReader.getFileNum();
				rowsArray = fileReader.getRowsArray();
			}
			
			//System.out.println("fileDealer");
			//fileDealer(currentDistributionList, rowsArray);
			
			//System.out.println(i + " " + rowsArray);
			//System.out.println(i + " " + currentDistributionList);
			
			GeneratorStatistics.circle.setDistributionRowArray(i,
					currentDistributionList, rowsArray);
		}

	}

	public void setOverlapDistributions() {
		
		// contain the final result
		Map<ArrayList<Integer>, ArrayList<HashMap<String, ArrayList<Pair<Pair<String, String>, Integer>>>>> latterAccumulations = 
				new HashMap<ArrayList<Integer>, ArrayList<HashMap<String, ArrayList<Pair<Pair<String, String>, Integer>>>>>();

		Map<ArrayList<Integer>, ArrayList<Pair<Pair<String, String>, Integer>>> keyToFormer = 
				new HashMap<ArrayList<Integer>, ArrayList<Pair<Pair<String, String>, Integer>>>();

		int size = GeneratorStatistics.overlap.getListLength();
		
		for (int i = 0; i < size; i++) {// for each overlap

			ArrayList<Integer> nowGroup = GeneratorStatistics.overlap.get(i);

			// firstPair::ArrayList to contain the first pair's distribution
			ArrayList<Pair<Pair<String, String>, Integer>> firstPair = new ArrayList<Pair<Pair<String, String>, Integer>>();

			// containerHash::ArrayList to contain those HashMap
			ArrayList<HashMap<String, ArrayList<Pair<Pair<String, String>, Integer>>>> containerHash = new ArrayList<HashMap<String, ArrayList<Pair<Pair<String, String>, Integer>>>>();

			// contain each pair's distribution in order so i use the arraylist
			for (int j = 0; j < nowGroup.size() - 1; j++) {

				Pair<Integer, Integer> nowPair = new Pair<Integer, Integer>(
						nowGroup.get(j), nowGroup.get(j + 1));
				
				int fileNum;
				ArrayList<Integer> rowsArray = new ArrayList<Integer>();
				
				if (j == 0) {
					
					ArrayList<Integer> pair = new ArrayList<Integer>();
					pair.add(nowGroup.get(j));
					pair.add(nowGroup.get(j+1));
					
					ArrayList<Map<String, Integer>> currentDistributionList = fileReader.readData(pair);
					
					if (i == 0) {
						fileNum = fileReader.getFileNum();
						rowsArray = fileReader.getRowsArray();
					}
					
					//System.out.println("fileDealer");
					//fileDealer(currentDistributionList, rowsArray);
					
					GeneratorStatistics.overlap.setDistributionRowArray(i,
							currentDistributionList, rowsArray);
					
				} else {
					
					Map<Pair<String,String>,Integer> jointDistri = fileReader.readData(nowPair.first_,nowPair.second_);
					
					Set<Pair<String,String>> valPairSet = jointDistri.keySet();
					Iterator<Pair<String,String>> iterPair = valPairSet.iterator();
					
					HashMap<String, ArrayList<Pair<Pair<String, String>, Integer>>> otherDistri = new HashMap<String, ArrayList<Pair<Pair<String, String>, Integer>>>();

					for (; iterPair.hasNext();) {

						Pair<String, String> PairOther = iterPair.next();
						Pair<Pair<String, String>, Integer> PairFrequent = new Pair<Pair<String, String>, Integer>(
								PairOther, jointDistri.get(PairOther));
						String startValue = PairOther.first_;

						if (otherDistri.get(startValue) == null) {

							ArrayList<Pair<Pair<String, String>, Integer>> accumulo = new ArrayList<Pair<Pair<String, String>, Integer>>();
							accumulo.add(PairFrequent);
							otherDistri.put(startValue, accumulo);

						} else {

							ArrayList<Pair<Pair<String, String>, Integer>> accumulo = otherDistri
									.get(startValue);
							int sum = accumulo.get(accumulo.size() - 1).second_;
							Pair<Pair<String, String>, Integer> PairAccumulo = new Pair<Pair<String, String>, Integer>(
									PairOther, sum + jointDistri.get(PairOther));
							accumulo.add(PairAccumulo);
							otherDistri.put(startValue, accumulo);

						}

					}
					containerHash.add(otherDistri);
					// otherDistri.clear();
				}

			}
			latterAccumulations.put(nowGroup, containerHash);

		}

		GeneratorStatistics.overlap.setLatterAccumulations(latterAccumulations);
	}

	public void getUncandiAccum(Set<Integer> s) {
		System.out.println("getUncandiAccum:");
//		System.out.println("set: " + s);
		
		Map<Integer, ArrayList<Pair<String, Integer>>> uncandiAccum = new HashMap<Integer, ArrayList<Pair<String, Integer>>>();
		Map<Integer, HashMap<String, Integer>> ud = fileReader.getUncandiDistri(s);

		Set<Integer> nums = ud.keySet();

//		int distinct = 0;
		
		for (Iterator<Integer> it = nums.iterator(); it.hasNext();) {

			Integer colNum = it.next();

			HashMap<String, Integer> ht = ud.get(colNum);

			Set<String> vals = ht.keySet();
			Iterator<String> ite = vals.iterator();

			String str = ite.next();
			Integer times = ht.get(str);

			ArrayList<Pair<String, Integer>> al = new ArrayList<Pair<String, Integer>>();
			Pair<String, Integer> pa = new Pair<String, Integer>(str, times);

			al.add(pa);

			for (; ite.hasNext();) {
				String str1 = ite.next();
				Integer times1 = ht.get(str1);
				times1 += al.get(al.size() - 1).second_;
				Pair<String, Integer> pa1 = new Pair<String, Integer>(str1, times1);
				al.add(pa1);
				
//				distinct++; //add the distinct number
			}

			uncandiAccum.put(colNum, al);
			

		}
//		DataGenerator.ucandi.setFlag(distinct);
//		System.out.println(distinct);
		GeneratorStatistics.ucandi.setUncandiAccum(uncandiAccum);

	}

}
